package com.zj.z11select.interceptor;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zj.z11select.constant.HttpStatus;
import com.zj.z11select.secruity.service.TokenService;
import com.zj.z11select.vo.BaseResult;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * token 拦截器
 * @author Duanyu
 * @date 2021-08-06 10:03
 */
@Component
@RequiredArgsConstructor
public class CheckTokenInterceptor implements HandlerInterceptor {

    /**
     * 试探型请求方法
     */
    private static final String OPTIONS = "OPTIONS";

    private final TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        //由于浏览器的预警机制，会发送一个保证能正常通信的试探性请求
        if (OPTIONS.equalsIgnoreCase(request.getMethod())) {
            return true;
        }
        //获取请求头中的token
        String token = request.getHeader("token");
        if (StringUtils.isBlank(token)){
            doResponse(response, BaseResult.error(HttpStatus.FORBIDDEN,"请先登录"));
        }else{
            try {
                return tokenService.verifyToken(token);
            }catch (Exception e){
                doResponse(response, BaseResult.error(HttpStatus.FORBIDDEN,"无效的Token"));
            }
        }
        return false;
    }

    /**
     * 响应JSON数据封装
     * @param response 响应体
     * @param vo 响应内容
     */
   private void doResponse(HttpServletResponse response, BaseResult vo){
       response.setContentType("application/json");
       response.setCharacterEncoding("utf-8");
       try (PrintWriter out = response.getWriter()) {
           String msg = new ObjectMapper().writeValueAsString(vo);
           out.print(msg);
           out.flush();
       } catch (IOException e) {
           e.printStackTrace();
       }

   }
}
